/**
 * Copyright 2011 Joe Choi, All rights reserved.
 */
package tao.data.structure.tree;

import java.util.ArrayList;
import java.util.List;

/**
 * The basic implementation of Tree interface
 * 
 * @author Joe Choi
 */
public abstract class AbstractTree<V> implements Tree<V> {	
	public AbstractTree(V value) {
		setValue(value);
	}
	
	@Override
	public int degree() {
		return(getSubtree().size());
	}
	
	@Override
	public V getValue() {
		return(value);
	}

	@Override
	public void setValue(V value) {
		this.value = value;
	}

	@Override
	public String toString() {
		return(generalize().toString());
	}
		
	@Override
	public boolean equals(Object obj) {
		if( (!(obj instanceof Tree)) || (obj == null) ) return(false);
		Tree<?> other = (Tree<?>) obj;
		return(this.generalize().equals(other.generalize()));
	}

	@Override
	public int hashCode() {
		return(this.generalize().hashCode());
	}
	
	@Override
	public List<V> generalize() {
		return(generalize(new PreOrderTraversal.Factory<V>(this)));
	}

	@Override
	public List<V> generalize(Traversal.Factory<V> factory) {
		final List<V> values = new ArrayList<V>();
		Traversal<V> traversal = factory.create();
		
		Traversal.Listener<V> visitor = new Traversal.Adaptor<V>() {
			public void traversedTree(Traversal.Event<V> event) { 
				values.add(event.getTree().getValue()); 
			}			
		};
		
		traversal.register(visitor);
		traversal.start();
		return(values);
	}
	
	protected <T extends Tree<V>> T buildFrom(Tree<V> source, PostOrderBuildHandler.Creation<V, V, T> creation) {
		Builder.Handler<V, V, T> handler = new PostOrderBuildHandler<V, V, T>(source, creation);
		Builder<V, T> builder = new ConcreteBuilder<V, V, T>(handler);
		return(builder.build().getTarget());
	}

	private V value;	
}